﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SyndicateDAO.DatabaseObject;

namespace SyndicateDAO.Classes
{
    public class DataBaseHelper<T> where T : IDataBaseObject
    {

        private DataContext dc = DataContextSingleton.Instance;

        //We assume that _obj is attached

        public bool Update()
        {
            try
            {
                dc.SubmitChanges();
                return true;
            }
            catch (Exception e)
            {
                Diagnostic.WriteToEventLog(e, e.Message);
                return false;
            }
        }
        public bool Insert(T _obj)
        {
            try
            {
                if (_obj.GetType().BaseType.Name != "Object")
                {
                    dc.GetTable(_obj.GetType().BaseType).InsertOnSubmit(_obj);
                }
                else dc.GetTable(_obj.GetType()).InsertOnSubmit(_obj);

                return Update();
            }
            catch (Exception e)
            {
                Diagnostic.WriteToEventLog(e, e.Message);
                return false;
            }
        }
        public bool Delete(T _obj)
        {
            try
            {
                if (_obj.GetType().BaseType.Name != "Object")
                {
                    dc.GetTable(_obj.GetType().BaseType).DeleteOnSubmit(_obj);
                }
                else dc.GetTable(_obj.GetType()).DeleteOnSubmit(_obj);
                Update();
                return true;
            }
            catch (Exception e)
            {
                Diagnostic.WriteToEventLog(e, e.Message);
                return false;
            }
        }
        [Obsolete]
        public bool Attach(T _obj)
        {
            try
            {
                dc = new DataContext();
                dc.GetTable(_obj.GetType()).Attach(_obj);
                dc.Refresh(System.Data.Linq.RefreshMode.KeepCurrentValues, _obj);
                dc.SubmitChanges();
                return true;
            }
            catch (Exception e)
            {
                Diagnostic.WriteToEventLog(e, e.Message);
                return false;
            }
        }
        [Obsolete]
        public bool AttachToContext(DataContext dc, T _obj)
        {
            try
            {
                //dc = new DataContext();
                dc.GetTable(_obj.GetType()).Attach(_obj);
                dc.Refresh(System.Data.Linq.RefreshMode.KeepCurrentValues, _obj);
                return true;
            }
            catch (Exception e)
            {
                Diagnostic.WriteToEventLog(e, e.Message);
                return false;
            }
        }


        public IQueryable<T> SelectAll()
        {
            try
            {
                if (typeof(T).BaseType.Name != "Object")
                {
                    return dc.GetTable(typeof(T).BaseType).OfType<T>();
                }
                else return dc.GetTable(typeof(T)).Cast<T>();
            }
            catch (Exception e)
            {
                Diagnostic.WriteToEventLog(e, e.Message);
                return new List<T>().AsQueryable();
            }
        }
        public IQueryable<T> SelectAll(DataContext _dc)
        {
            try
            {
                if (typeof(T).BaseType.Name != "Object")
                {
                    return _dc.GetTable(typeof(T).BaseType).OfType<T>();
                }
                else return _dc.GetTable(typeof(T)).Cast<T>();
            }
            catch (Exception e)
            {
                Diagnostic.WriteToEventLog(e, e.Message);
                return new List<T>().AsQueryable();
            }
        }
        public T SelectSingle(int id)
        {
            try
            {
                return this.SelectAll().SingleOrDefault(r => r.id == id);
            }
            catch (Exception e)
            {
                Diagnostic.WriteToEventLog(e, e.Message);
                return default(T);
            }
        }
        public T SelectSingle(int id, DataContext dc)
        {
            try
            {
                return this.SelectAll(dc).SingleOrDefault(r => r.id == id);
            }
            catch (Exception e)
            {
                Diagnostic.WriteToEventLog(e, e.Message);
                return default(T);
            }
        }
    }
}
